/*  */
#include <stdlib.h>
#include "cstdlib.h"
#include "../table.h"
#include "../interpreter.h"
#include "platform.h"


static int Stdlib_ZeroValue = 0;


void Cstdlib::StdlibAtof(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->fP = atof((char *)param[0]->val->pointer);
}

void Cstdlib::StdlibAtoi(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = atoi((char *)param[0]->val->pointer);
}

void Cstdlib::StdlibAtol(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = atol((char *)param[0]->val->pointer);
}

void Cstdlib::StdlibStrtod(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->fP = strtod((char *)param[0]->val->pointer, (char **)param[1]->val->pointer);
}

void Cstdlib::StdlibStrtol(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = strtol((char *)param[0]->val->pointer,
                                       (char **)param[1]->val->pointer, param[2]->val->integer);
}

void Cstdlib::StdlibStrtoul(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = strtoul((char *)param[0]->val->pointer,
                                        (char **)param[1]->val->pointer, param[2]->val->integer);
}

void Cstdlib::StdlibMalloc(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = malloc(param[0]->val->integer);
}

void Cstdlib::StdlibCalloc(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = calloc(param[0]->val->integer,
        param[1]->val->integer);
}

void Cstdlib::StdlibRealloc(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = realloc(param[0]->val->pointer,
        param[1]->val->integer);
}

void Cstdlib::StdlibFree(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    free(param[0]->val->pointer);
}

void Cstdlib::StdlibRand(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = rand();
}

void Cstdlib::StdlibSrand(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    srand(param[0]->val->integer);
}

void Cstdlib::StdlibAbort(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    Platform::ProgramFail(parser, "abort");
}

void Cstdlib::StdlibExit(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    Platform::PlatformExit(parser->pc, param[0]->val->integer);
}

void Cstdlib::StdlibGetenv(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = getenv((char *)param[0]->val->pointer);
}

void Cstdlib::StdlibSystem(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = system((char *)param[0]->val->pointer);
}

#if 0
void Cstdlib::StdlibBsearch(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->pointer = bsearch(param[0]->val->pointer,
        param[1]->val->pointer, param[2]->val->integer, param[3]->val->integer,
        (int (*)())param[4]->val->pointer);
}
#endif

void Cstdlib::StdlibAbs(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = abs(param[0]->val->integer);
}

void Cstdlib::StdlibLabs(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = labs(param[0]->val->integer);
}

#if 0
void Cstdlib::StdlibDiv(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = div(param[0]->val->integer,
        param[1]->val->integer);
}

void Cstdlib::StdlibLdiv(ParseState *parser, Value *returnValue, Value **param, int numArgs)
{
    returnValue->val->integer = ldiv(param[0]->val->integer,
        param[1]->val->integer);
}
#endif

#if 0
/* handy structure definitions */
const char StdlibDefs[] = "\
typedef struct { \
    int quot, rem; \
} div_t; \
\
typedef struct { \
    int quot, rem; \
} ldiv_t; \
";
#endif

/* all stdlib.h functions */
const LibraryFunction Cstdlib::StdlibFunctions[] =
{
    {Cstdlib::StdlibAtof, "float atof(char *);"},
    {Cstdlib::StdlibStrtod, "float strtod(char *,char **);"},
    {Cstdlib::StdlibAtoi, "int atoi(char *);"},
    {Cstdlib::StdlibAtol, "int atol(char *);"},
    {Cstdlib::StdlibStrtol, "int strtol(char *,char **,int);"},
    {Cstdlib::StdlibStrtoul, "int strtoul(char *,char **,int);"},
    {Cstdlib::StdlibMalloc, "void *malloc(int);"},
    {Cstdlib::StdlibCalloc, "void *calloc(int,int);"},
    {Cstdlib::StdlibRealloc, "void *realloc(void *,int);"},
    {Cstdlib::StdlibFree, "void free(void *);"},
    {Cstdlib::StdlibRand, "int rand();"},
    {Cstdlib::StdlibSrand, "void srand(int);"},
    {Cstdlib::StdlibAbort, "void abort();"},
    {Cstdlib::StdlibExit, "void exit(int);"},
    {Cstdlib::StdlibGetenv, "char *getenv(char *);"},
    {Cstdlib::StdlibSystem, "int system(char *);"},
/*    {Cstdlib::StdlibBsearch, "void *bsearch(void *,void *,int,int,int (*)());"}, */
/*    {Cstdlib::StdlibQsort, "void *qsort(void *,int,int,int (*)());"}, */
    {Cstdlib::StdlibAbs, "int abs(int);"},
    {Cstdlib::StdlibLabs, "int labs(int);"},
#if 0
    {Cstdlib::StdlibDiv, "div_t div(int);"},
    {Cstdlib::StdlibLdiv, "ldiv_t ldiv(int);"},
#endif
    {NULL, NULL}
};

/* creates various system-dependent definitions */
void Cstdlib::StdlibSetupFunc(Interpreter *pc)
{
    /* define NULL, TRUE and FALSE */
    if (!(pc, MyTable::TableStrRegister(pc, "NULL")))
        (pc, NULL, "NULL", &pc->intType,
            (union AnyValue*)&Stdlib_ZeroValue, false);
}

